package com.github.elliot.gatewaycenter.security.converter;


import com.github.elliot.gatewaycenter.common.ResponseEnum;
import com.github.elliot.gatewaycenter.common.constant.AuthConstant;
import com.github.elliot.gatewaycenter.domain.AdminUserPO;
import com.github.elliot.gatewaycenter.util.WebExchangeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.authentication.ServerFormLoginAuthenticationConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * 把用户上传的认证信息转换成UsernamePasswordAuthenticationToken
 */
@Component
public class UsernamePasswordAuthenticationConverter extends ServerFormLoginAuthenticationConverter {

    @Override
    public Mono<Authentication> convert(ServerWebExchange exchange) {
        HttpHeaders headers = exchange.getRequest().getHeaders();
        String host = Objects.requireNonNull(headers.getHost()).getHostName();
        return WebExchangeUtils.parseRequestBodyToJson(exchange)
                .flatMap(jsonNode -> {
                    String userName = jsonNode.has(AuthConstant.USERNAME_PARAMETER) ?
                            jsonNode.get(AuthConstant.USERNAME_PARAMETER).asText() : null;
                    String password = jsonNode.has(AuthConstant.PASSWORD_PARAMETER) ?
                            jsonNode.get(AuthConstant.PASSWORD_PARAMETER).asText() : null;
                    String verificationCode = jsonNode.has(AuthConstant.VERIFICATION_PARAMETER) ?
                            jsonNode.get(AuthConstant.VERIFICATION_PARAMETER).asText() : null;
                    // 创建Authentication对象
                    if (StringUtils.isNoneBlank(userName) && StringUtils.isNoneBlank(password)) {
                        AdminUserPO adminUserPo = new AdminUserPO(userName, verificationCode, host);
                        return Mono.just(new UsernamePasswordAuthenticationToken(adminUserPo, password));
                    } else {
                        return Mono.error(new BadCredentialsException(ResponseEnum.LOGIN_FAILED.getMsg()));
                    }
                });

    }

}

